// DesertedCity.cpp : Defines the class behaviors for the application.
//

#include "Common.h"
#include "OpenGLFont.h"
#include "Graphics/OpenGL/OpenGLRenderer.h"

#if defined WIN32
#include "windows.h"
#endif

using namespace RayFrame;

OpenGLFont::OpenGLFont()
{
}

OpenGLFont::~OpenGLFont()
{
  KillFont();
}

bool OpenGLFont::BuildSystemFont(STRING fontName, int fontHeight)
{
#if defined WIN32
  return BuildSystemFontWin32(fontName, fontHeight);
#elif defined LINUX
  return BuildSystemFontLinux(fontName, fontHeight);
#endif
}

#if defined LINUX
bool OpenGLFont::BuildSystemFontLinux(STRING fontName, int fontHeight)
{
  return false;
}
#elif defined WIN32
bool OpenGLFont::BuildSystemFontWin32(STRING fontName, int fontHeight)
{
   HDC hDC =::GetDC(HWND_DESKTOP);
   assert(hDC);

   int tFontHeight = -1 * fontHeight;

   NormalFontBase = glGenLists(96);                // Storage For 96 Characters
   assert(NormalFontBase);

   HFONT font;
   V( (font = CreateFont( -tFontHeight,     // Height Of Font
                0,                          // Width Of Font
                0,                          // Angle Of Escapement
                0,                          // Orientation Angle
                FW_BOLD,                    // Font Weight
                TRUE,                       // Italic
                FALSE,                      // Underline
                FALSE,                      // Strikeout
                ANSI_CHARSET,               // Character Set Identifier
                OUT_TT_PRECIS,              // Output Precision
                CLIP_DEFAULT_PRECIS,        // Clipping Precision
                ANTIALIASED_QUALITY,        // Output Quality
                FF_DONTCARE|DEFAULT_PITCH,  // Family And Pitch
                fontName.c_str() )) );      // Font Name
   

  HFONT oldfont = (HFONT)SelectObject(hDC, font);         // Selects The Font We Want
  
  wglUseFontBitmaps(hDC, 32, 96, NormalFontBase);      // Builds 96 Characters Starting At Character 32
  
  SelectObject(hDC, oldfont);              // Selects The Font We Want to return to
  DeleteObject(font);                  // Delete The Font

  SetBkMode(hDC,TRANSPARENT);   

  m_fontType = SystemFont;

  return true;
}



///////////GDI, λͼ���� ������������
void OpenGLFont::BuildGDIFont(LPCTSTR lpszFacename, int fontWeights, int fontHeight)
{
  // Font Weights
  #define FW_DONTCARE         0
  #define FW_THIN             100
  #define FW_EXTRALIGHT       200
  #define FW_LIGHT            300
  #define FW_NORMAL           400
  #define FW_MEDIUM           500
  #define FW_SEMIBOLD         600
  #define FW_BOLD             700
  #define FW_EXTRABOLD        800
  #define FW_HEAVY            900
  
  int tfontHeight = -1 * fontHeight;

  m_hGDIFont = CreateFont(tfontHeight, 0, 0, 0, fontWeights, 0, 0, 0, GB2312_CHARSET,
                0, 0, 0, FF_MODERN, lpszFacename);
  
  m_fontType = GDIFont;
}

//void OpenGLFont::PrintfChtext(int x, int y, LPCTSTR lpszText)
//{
//    CBitmap bitmap;
//    BITMAP bm;
//    SIZE size;
//    
//    HDC MDC = ::CreateCompatibleDC(NULL);
//    SelectObject(MDC, m_hGDIFont);
//    
//    ::GetTextExtentPoint32(MDC,lpszText,strlen(lpszText),&size);
//
//    bitmap.CreateBitmap(size.cx, size.cy, 1, 1, NULL);
//
//    HBITMAP oldBmp=(HBITMAP)SelectObject(MDC,bitmap);
//
//    SetBkColor  (MDC, RGB(0,     0,   0));
//    SetTextColor(MDC, RGB(255, 255, 255));
//
//    TextOut(MDC, 0, 0, lpszText, strlen(lpszText));
//
//    bitmap.GetBitmap(&bm);
//    size.cx = (bm.bmWidth + 31) & (~31);
//
//    int bufsize = size.cy * size.cx;
//
//    struct {  
//          BITMAPINFOHEADER bih;
//        RGBQUAD col[2];
//        }bic; 
//
//    BITMAPINFO *binf = (BITMAPINFO *)&bic; 
//    binf->bmiHeader.biSize     = sizeof(binf->bmiHeader);
//    binf->bmiHeader.biWidth    = bm.bmWidth;
//    binf->bmiHeader.biHeight   = bm.bmHeight;
//    binf->bmiHeader.biPlanes   = 1;   
//    binf->bmiHeader.biBitCount = 1;
//    binf->bmiHeader.biCompression = BI_RGB;
//    binf->bmiHeader.biSizeImage   = bufsize; 
//
//    UCHAR* Bits = new UCHAR[bufsize];  
//    ::GetDIBits(MDC,bitmap, 0, bm.bmHeight, Bits, binf, DIB_RGB_COLORS); 
//                                      
//    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
//
//    //glRasterPos2i(x, y); 
//    glWindowPos2i(x, y);
//    glBitmap(size.cx, size.cy, 0, 0, 0, 0, Bits); 
//
//    delete Bits;    
//    SelectObject(MDC, oldBmp);  
//    ::DeleteDC(MDC);
//}

void OpenGLFont::PrintGDIText(GLint x, GLint y, STRING str)
{
  if(m_fontType != GDIFont)
    return;

  glLoadIdentity();
  glPushAttrib(GL_CURRENT_BIT | GL_LIGHTING_BIT);

  glDisable(GL_TEXTURE_2D); 
  glDisable(GL_LIGHTING); 

  glColor4f(m_color[0], m_color[1], m_color[2], m_color[3]);  

  //PrintfChtext (x, y, str.c_str()); 
  
  glPopAttrib();
}

#endif

void OpenGLFont::PrintSystemFontText(GLint x, GLint y, const char *string)  
{
  // Pushes The Display List Bits
  glPushAttrib(GL_LIST_BIT | GL_CURRENT_BIT |  GL_ENABLE_BIT | GL_LIGHTING_BIT);
  glDisable (GL_BLEND);
  glDisable (GL_DITHER);
  glDisable (GL_FOG);
  glDisable (GL_LIGHTING);
  glDisable (GL_TEXTURE_1D);
  glDisable (GL_TEXTURE_2D);
  glDisable (GL_TEXTURE_3D);
  glShadeModel (GL_FLAT);
  glBindTexture(GL_TEXTURE_2D, 0);
  glDisable(GL_TEXTURE_2D);
  //glDisable( GL_COLOR_MATERIAL );
  glColor3f(m_color[0], m_color[1], m_color[2]);

  glWindowPos2iARB(x, y);
            
  glListBase(NormalFontBase - 32);          // Sets The Base Character to 32
  glCallLists(strlen(string), GL_UNSIGNED_BYTE, string);  // Draws The Display List Text

  glPopAttrib();  
}

////////////�����弯������ȡ�����ַ�
//void OpenGLFont::BuildTextureFont(GLuint fonttex, int fontHeight)
//{
//  TextureFontFont = fonttex;
//
//  float  cx;                      // Holds Our X Character Coord
//  float  cy;                      // Holds Our Y Character Coord
//
//  glEnable(GL_TEXTURE_2D);
//
//  TextureFontBase = glGenLists(256);          // Creating 256 Display Lists
//
//  glBindTexture(GL_TEXTURE_2D, TextureFontFont);      // Select Our Font Texture
//
//  for(int loop=0; loop<256; loop++)          // Loop Through All 256 Lists
//  {
//    cx=float(loop%16)/16.0f;            // X Position Of Current Character
//    cy=float(loop/16)/16.0f;            // Y Position Of Current Character
//
//    glNewList(TextureFontBase + loop, GL_COMPILE);  // Start Building A List
//      glBegin(GL_QUADS);              // Use A Quad For Each Character
//        glTexCoord2f(cx,1-cy-0.0625f);      // Texture Coord (Bottom Left)
//        glVertex2i(0,0);            // Vertex Coord (Bottom Left)
//        glTexCoord2f(cx+0.0625f,1-cy-0.0625f);  // Texture Coord (Bottom Right)
//        glVertex2i(fontHeight, 0);        // Vertex Coord (Bottom Right)
//        glTexCoord2f(cx+0.0625f,1-cy);      // Texture Coord (Top Right)
//        glVertex2i(fontHeight,fontHeight);    // Vertex Coord (Top Right)
//        glTexCoord2f(cx,1-cy);          // Texture Coord (Top Left)
//        glVertex2i(0, fontHeight);        // Vertex Coord (Top Left)
//      glEnd();                  // Done Building Our Quad (Character)
//      glTranslated(fontHeight,0,0);        // Move To The Right Of The Character
//    glEndList();                  // Done Building The Display List
//  }                          // Loop Until All 256 Are Built
//
//  glDisable(GL_TEXTURE_2D);
//
//  m_fontType = TextureFont;
//}

//
//void OpenGLFont::PrintTextureText(GLint x, GLint y, char *string, int TextureSet)
//{
//  if (TextureSet > 1)TextureSet = 1;
//  if (TextureSet < 0)TextureSet = 0;
//
//  glPushAttrib(GL_CURRENT_BIT | GL_LIGHTING_BIT | GL_ENABLE_BIT|  GL_LIST_BIT);
//  glDisable(GL_LIGHTING); 
//
//    glEnable(GL_TEXTURE_2D);
//  glBindTexture(GL_TEXTURE_2D, TextureFontFont);    // Select Our Font Texture
//
//  glDisable(GL_DEPTH_TEST);              // Disables Depth Testing
//  glEnable(GL_BLEND);
//  glBlendFunc(GL_SRC_ALPHA,GL_ONE);
//
//  glColor4f(m_color[0], m_color[1], m_color[2], m_color[3]);  
//
//  glMatrixMode(GL_PROJECTION);            // Select The Projection Matrix
//  glPushMatrix();                    // Store The Projection Matrix
//  
//  glLoadIdentity();                  // Reset The Projection Matrix
//  glOrtho(0, OpenGLRenderer::InstanceRef().GetViewportWidth(), 0, ,-1,1);      // Set Up An Ortho Screen
//
//  glMatrixMode(GL_MODELVIEW);              // Select The Modelview Matrix
//  glPushMatrix();                    // Store The Modelview Matrix
//  
//  glLoadIdentity();                  // Reset The Modelview Matrix
//  glTranslated(x,y,0);                // Position The Text (0,0 - Bottom Left)
//  
//  glListBase(TextureFontBase-32 + (128 * TextureSet));// Choose The Font Set (0 or 1)
//  glCallLists(strlen(string),GL_UNSIGNED_BYTE,string);// Write The Text To The Screen
//  
//  glMatrixMode(GL_PROJECTION);            // Select The Projection Matrix
//  glPopMatrix();                    // Restore The Old Projection Matrix
//  glMatrixMode(GL_MODELVIEW);              // Select The Modelview Matrix
//  glPopMatrix();                    // Restore The Old Projection Matrix
//  
//  glDisable(GL_BLEND);
//  glEnable(GL_DEPTH_TEST);              // Enables Depth Testing
//    glDisable(GL_TEXTURE_2D);
//
//  glPopAttrib();
//}

void OpenGLFont::KillFont()
{
  switch(m_fontType)
  {
  case SystemFont:
    glDeleteLists(NormalFontBase, 96); // Delete All 96 Characters
    break;
  case GDIFont:
    break;
  default:
    return;
  }
  m_fontType = NoFont;
}

